﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Cesave.Domain.PermisosModule.Entities;
using Cesave.Infrastructure.Data.Core;
using Cesave.Domain.PermisosModule.Contracts.Municipios;
using Cesave.Infrastructure.Data.PermisosModule.Context;
using Cesave.Infrastructure.CrossCutting.Logging;
using Cesave.Domain.Core.Specification;

namespace Cesave.Infrastructure.Data.PermisosModule.Repositories
{
	/// <summary>
	/// 
	/// </summary>
	public class MunicipioRepository
		: GenericRepositoryEx<Municipio>, IMunicipioRepository
	{
		#region Constructor

		/// <summary>
		/// 
		/// </summary>
		/// <param name="context"></param>
		/// <param name="traceManager"></param>
		public MunicipioRepository(IPermisosModuleContext context, ITraceManager traceManager) 
			: base(context, traceManager)
		{
		}

		#endregion

		#region IMunicipioRepository Members

		/// <summary>
		/// 
		/// </summary>
		/// <param name="municipiosByEstadoSpecification"></param>
		/// <returns></returns>
		public IEnumerable<Municipio> FindMunicipiosByEstadoSpecification(MunicipiosByEstadoSpecification municipiosByEstadoSpecification)
		{
			if (municipiosByEstadoSpecification == null)
				throw new ArgumentNullException("municipiosByEstadoSpecification");
			return GetFilteredElements(municipiosByEstadoSpecification.SatisfiedBy(), municipio => municipio.Nombre, true);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="municipiosByEstadoSpecification"></param>
		/// <param name="status"></param>
		/// <returns></returns>
		public IEnumerable<Municipio> FindMunicipiosByEstadoSpecificationAndStatus(MunicipiosByEstadoSpecification municipiosByEstadoSpecification, bool status = true)
		{
			if (municipiosByEstadoSpecification == null)
				throw new ArgumentNullException("municipiosByEstadoSpecification");
			Specification<Municipio> municipiosSpecification = new TrueSpecification<Municipio>();
			municipiosSpecification &= municipiosByEstadoSpecification;
			municipiosSpecification &= new MunicipiosByStatusSpecification(status);
			return GetFilteredElements(municipiosSpecification.SatisfiedBy(), municipio => municipio.Nombre, true);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="municipiosByDistritoSpecification"></param>
		/// <returns></returns>
		public IEnumerable<Municipio> FindMunicipiosByDistritoSpecification(MunicipiosByDistritoSpecification municipiosByDistritoSpecification)
		{
			if (municipiosByDistritoSpecification == null)
				throw new ArgumentNullException("municipiosByDistritoSpecification");
			return GetFilteredElements(municipiosByDistritoSpecification.SatisfiedBy(), municipio => municipio.Nombre, true);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="municipiosByDistritoSpecification"></param>
		/// <param name="status"></param>
		/// <returns></returns>
		public IEnumerable<Municipio> FindMunicipiosByDistritoSpecificationAndStatus(MunicipiosByDistritoSpecification municipiosByDistritoSpecification, bool status = true)
		{
			if (municipiosByDistritoSpecification == null)
				throw new ArgumentNullException("municipiosByDistritoSpecification");
			Specification<Municipio> municipiosSpecification = new TrueSpecification<Municipio>();
			municipiosSpecification &= municipiosByDistritoSpecification;
			municipiosSpecification &= new MunicipiosByStatusSpecification(status);
			return GetFilteredElements(municipiosSpecification.SatisfiedBy(), municipio => municipio.Nombre, true);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="municipioByGuidSpecification"></param>
		/// <returns></returns>
		public Municipio FindMunicipioByGuidSpecification(MunicipioByGuidSpecification municipioByGuidSpecification)
		{
			if (municipioByGuidSpecification == null)
				throw new ArgumentNullException("municipioByGuidSpecification");
			return GetBySpec(municipioByGuidSpecification).FirstOrDefault();
		}

		#endregion
	}
}
